一、基本语法
Java是一种面向对象语言,所以必须构造一个对象,这个对象的类需要有一个方法能包含所需的代码。如下:
如果使用Lambda表达式,则使用代码更改为:
简化
在这里,编译器可以推导出first和second必然是字符串,参数类型可以省略不写;方法体里只有一行,亦可简化。如下:
无参
即使lambda表达式没有参数,仍然要提供括号,就像无参数方法一样:
一参
如果方法只有一个参数,而且这个参数的类型可以推导得出,那么甚至还可以省略小括号:
注意
1)无需指定lambda表达式的返回类型,因为返回类型总是会由上下文推导得出。
2)如果一个lambda表达式只在某些分支返回一个值,而在另外一些分支不返回值,这是不合法的。例如,(int x) -> { if (x >= 0) return 1; }就不合法。
Demo
|
|
二、函数式接口
对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这个接口称为函数式接口。如上例中的Comparator接口,或者java.util.function包中的接口Predicate:
ArrayList类有一个removeIf方法它的参数就是一个Predicate。这个接口专门用来传递lambda表达式。
三、方法引用
表达式System.out::println是一个方法引用,等价于lambda表达式x -> System.out.println(x)。又如下列两行代码等同:
操作符 “::” 用来分割方法名与对象或类名。主要分为三种情况:
对于第三种情况,第一个参数会成为方法的目标。
注意:对于重载方法,编译器会尝试从上下文中找出你指的那一个方法;方法引用不能独立存在,总是会转换为函数式接口的实例;方法引用中可以使用this和super参数,例如this::equals等同于x -> this.equals(x);使用super作为目标,会调用方法的超类版本,格式为super::instanceMethod;this是指创建lambda表达式的方法所属的对象,super同理。
四、构造器引用
构造器引用与方法引用类似,只不过方法名为new。例如,Person::new是Person构造器的一个引用。至于哪一个构造器,这取决于上下文。假如你有一个字符串列表,并把它转换为Person对象数组,其如下:
根据上下文,编译器会选择一个String参数的构造器。可以用数组类型建立构造器引用。例如,int[]::new,这等价于lambda表达式x -> new int[x]。
五、变量
lambda表达式中捕获的变量必须实际上是最终变量,即这个变量初始化之后就不会再为它赋新值。如下例中的text总是指示同一个String对象,所以此处合法。
当lambda表达式捕获外围作用域中变量的,无论是外部改变还是内部改变都不合法的。